#include "gui.h"

//Ces variables globales sont mises ici parce que de toute facon,
//GUI_init doit etre le premier a leur coller une valeur
GtkWidget* fenetre=NULL;
GtkWidget* fenetre_vbox=NULL;
GtkWidget* debug_label=NULL;
GtkWidget* container_monde=NULL;
GtkWidget* container_aeroport=NULL;
GtkWidget* g_monde = NULL;
GtkWidget* g_aeroport = NULL;
GooCanvasItem* r_monde = NULL;
GooCanvasItem* r_aeroport = NULL;
gboolean gui_started=FALSE;
char _settings[MAX_SETTINGS][2][MAX_SETTING_LENGTH];
int _nb_settings=0;

//Scrolling & Zoom
gboolean mouse_down=FALSE;
int _x=50;
int _y=50;
gdouble last_mouse_x=-1;
gdouble last_mouse_y=-1;
GtkAdjustment* hadj;
GtkAdjustment* vadj;
gdouble hadj_max;
gdouble hadj_min;
gdouble vadj_max;
gdouble vadj_min;


//modes (boutons toggle & possibilités clic)
//mis à 0 normalement
gboolean mode_deplacement;
gboolean mode_selection;
gboolean mode_zoom;
GtkWidget* bouton_zoom;
GtkWidget* bouton_selection;
GtkWidget* bouton_deplacer;


gboolean on_motion_notify(GtkWidget*item,GtkAdjustment*target,GdkEventMotion*event,gpointer data)
{
	gdouble x_offset, y_offset;
	gdouble hvalue,vvalue;
	gdouble tp;
	gdouble slow_rate = 5;
	if(mouse_down)
	{
		if(last_mouse_x == -1 || last_mouse_y == -1)
		{
			last_mouse_x = event->x;
			last_mouse_y = event->y;
		}
		x_offset = (event->x -last_mouse_x)/slow_rate;
		y_offset = (event->y - last_mouse_y)/slow_rate;
		hvalue = gtk_adjustment_get_value(hadj);
		tp = hvalue-x_offset;
		#if 1
		if(tp > hadj_max)
		{
			tp = hadj_max;
		}
		else if (tp < hadj_min)
		{
			tp = hadj_min;
		}
		#endif
		gtk_adjustment_set_value(hadj,tp);
		gtk_adjustment_changed(hadj);
		vvalue = gtk_adjustment_get_value(vadj);
		tp = vvalue-y_offset;
		#if 1
		if(tp > vadj_max)
			tp = vadj_max;
		else if (tp < vadj_min)
			tp = vadj_min;
		#endif
		gtk_adjustment_set_value(vadj,tp);
		gtk_adjustment_changed(vadj);
	}
	return FALSE;
}

gboolean on_press(GooCanvasItem*item,GooCanvasItem*target,GdkEventButton*event,gpointer data)
{
	g_print("mouse_pressed\n");
	mouse_down = TRUE;
	return FALSE;
}

gboolean on_release(GooCanvasItem*item,GooCanvasItem*target,GdkEventButton*event,gpointer data)
{
	g_print("mouse_released\n");
	mouse_down = FALSE;
	last_mouse_x = last_mouse_y = -1;
	return FALSE;
}

gboolean set_scroll_limits(GtkWidget*emitter,GtkWidget*target,GdkEvent*evt,gpointer data)
{
	gdouble hpage_size,vpage_size;
	g_object_get(hadj,"lower",&hadj_min,"upper",&hadj_max);
	g_object_get(vadj,"lower",&vadj_min,"upper",&vadj_max);
	g_object_get(hadj,"page-size",&hpage_size);
	g_object_get(vadj,"page-size",&vpage_size);
	hadj_max = hadj_max - hpage_size;
	vadj_max = vadj_max - vpage_size;
	//g_printf("did set LIMITS : horiz[%f,%f],vertic%f,%f\n",hadj_min,hadj_max,vadj_min,vadj_max);
	return FALSE;
}

#define MONDE_SCALE_FACTOR 3

#if 1
gboolean move_pic(gpointer gciImage)
{
	_x += 1;
	_y += 1;
	msg("x,y:%d,%d\n",_x,_y);
	goo_canvas_item_set_simple_transform(GOO_CANVAS_ITEM(gciImage),_x,_y,1,0);
	return TRUE;
}
#endif

//glade_filename == NULL => default : "GUI.glade"
int GUI_init(int* argc,char*** argv)
{
	GladeXML *xml;
	int success;
	//init gtk
	gtk_init(argc, argv);

	success = set_settings_file(SETTINGS_FILENAME);
	if(!success)
	{
		msg("GUI_init:je ne peux travailler sans %s\n",SETTINGS_FILENAME);
	}
	//chargement xml
	xml = glade_xml_new(get_setting("glade"), NULL, NULL);
	if(!xml)
	{
		//message d'erreur de GTK automatique ici
		exit(0);
	}
	/* connect the signals in the interface */
	glade_xml_signal_autoconnect(xml);

	//fenetre principale
	fenetre = glade_xml_get_widget(xml,"fenetre");

	//container des deux vues
	container_monde = glade_xml_get_widget(xml,"container_monde");
	container_aeroport = glade_xml_get_widget(xml,"container_aeroport");
	bouton_zoom = glade_xml_get_widget(xml,"outil_zoomer");
	bouton_selection = glade_xml_get_widget(xml,"outil_selection");
	bouton_deplacer = glade_xml_get_widget(xml,"outil_decaler");

	//canevas monde et aeroport
	g_monde = goo_canvas_new();
	g_aeroport = goo_canvas_new();

	//configuration des canevas
	gtk_widget_set_size_request(g_monde,WIDTH*MONDE_SCALE_FACTOR,HEIGHT*MONDE_SCALE_FACTOR);
	goo_canvas_set_bounds(GOO_CANVAS(g_monde),0,0,WIDTH*MONDE_SCALE_FACTOR,HEIGHT*MONDE_SCALE_FACTOR);
	goo_canvas_set_bounds(GOO_CANVAS(g_aeroport),0,0,1000,1000);
	hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(container_monde));
	vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(container_monde));
	
	//a lancer un peu après le lancement de l'application
	g_signal_connect(g_monde,"expose-event",(GtkSignalFunc)set_scroll_limits,NULL);
	
	gtk_widget_show(g_monde);
	gtk_widget_show(g_aeroport);

	//prise des racines dessinables
	r_monde = goo_canvas_get_root_item(GOO_CANVAS(g_monde));
	r_aeroport = goo_canvas_get_root_item(GOO_CANVAS(g_aeroport));
	
	//ajout dans les container des deux vues
	gtk_container_add(GTK_CONTAINER(container_monde),g_monde);
	gtk_container_add(GTK_CONTAINER(container_aeroport),g_aeroport);

	#if 1
	//dessin du contenu des vues
	success = dessiner_monde();
	if(!success)
	{
		msg("GUI_init : echec de dessin_monde()\n");
		//return 0; //on fait lancer l'interface graphique quand meme
	}
	#endif
	//label de debuggage
	#if defined DEBUG && defined USE_GUI
	fenetre_vbox = glade_xml_get_widget(xml,"fenetre_vbox");
	debug_label = gtk_label_new("");
	gtk_box_pack_start(GTK_BOX(fenetre_vbox),debug_label,FALSE,TRUE,0);
	#endif
	gtk_window_maximize(GTK_WINDOW(fenetre));
	gtk_widget_show_all(fenetre);

	/* start the event loop */
	gui_started = TRUE;
	gtk_main();
	return 1;
}

//requiert GUI_init appelé
int dessiner_monde()
{
	GdkPixbuf* fp=NULL;
	GooCanvasItem* fond=NULL;
	GError* erreur=NULL;


	//ouverture fichier
	fp = gdk_pixbuf_new_from_file_at_scale(get_setting("fond_monde"),WIDTH*MONDE_SCALE_FACTOR,HEIGHT*MONDE_SCALE_FACTOR,FALSE,&erreur);

	if(erreur)
	{
		msg("dessiner_monde:%s\n",erreur->message);
		g_error_free(erreur);

		return 0;
	}


	//creation canvas item et écriture sur root
	fond = goo_canvas_image_new(r_monde,fp,0,0);//"width",(gdouble)WIDTH*2,"height",(gdouble)HEIGHT*2,NULL);
	g_signal_connect(fond,"motion_notify_event",(GtkSignalFunc)on_motion_notify,NULL);
	g_signal_connect(fond,"button_press_event",(GtkSignalFunc)on_press,NULL);
	g_signal_connect(fond,"button_release_event",(GtkSignalFunc)on_release,NULL);
	//goo_canvas_item_set_simple_transform(r_monde,0,0,1,0);
	//g_timeout_add(100,move_pic,fond); // tous les dixièmes de seconde

	return 1;
}

//w,h = (0,0) => taille d'origine
GooCanvasItem* image_item(GooCanvasItem* root_canvas,char* setting_name,int width,int height,int x,int y)
{
	GooCanvasItem* a;
	GdkPixbuf* b;
	GError* erreur;
	if(width<=0 || height <=0)
		b = gdk_pixbuf_new_from_file(get_setting(setting_name),&erreur);
	else								//FALSE : pas de préserv de l'aspect ratio
		b = gdk_pixbuf_new_from_file_at_scale(get_setting(setting_name),width,height,FALSE,&erreur);
	if(erreur)
	{
		msg("image_item:%s\n",erreur->message);
		g_error_free(erreur);
		return NULL;
	}
	a = goo_canvas_image_new(root_canvas,b,x,y);
	return a;
}

//pas besoin d'utiliser le retour de la fonction
//NOTE : DANS LA VUE MONDE ON PEUT AVOIR DES INFORMATIOSN SUR LES AVIONS EN VOLS ET LES AEROPORTS
//DANS LA VUE AEROPORT : ON PEUT AVOIR DES INFORMATIONS SUR LES AVIONS SEULEMENT
GooCanvasItem* faire_info_bulle(int quelle_vue,GooCanvasItem*sur_quel_objet)
{
	//on aura toujours affaire pour les avions et les points aeroports a goo canvas image_item
	//donc on peut lire les prop x et y tranquillou
	gdouble x,y;
	GooCanvasItem* bul;
	GooCanvasItem* root;
	//on prend la position de l'objezt
	g_object_get(sur_quel_objet,"x",&x);
	g_object_get(sur_quel_objet,"y",&y);
	//si on est dans la vue aéroport
	//alors c'est simple, le truc ne peut être qu'un avion
	if(quelle_vue == VUE_AEROPORT)
	{
		root = r_aeroport;
	}
	else
	{
		root = r_monde;
	}

	//creation de la bulle
	bul = image_item(root,"infobulle",0,0,x,y);
	//avec champ de texte & bouton fermer
	//=> le contenu du champ de texte / la fonction a appeler dépend de l'avion que c'est
	
	//callbacks frequents pour qu'il y ait du refresh (jusqu'à ce que la bulle soit fermée)

	//configuration callback fermeture bulle => destruction bulle

	return bul;
}

gboolean on_point_aeroport_presse(GooCanvasItem*aeroport,GooCanvasItem*target,GdkEventButton*event,gpointer data)
{
	faire_info_bulle(VUE_MONDE,aeroport);
}

//pas nécessaire d'utiliser le retour de cette fct
GooCanvasItem* nouveau_point(int x,int y,int id_aeroport)
{
	int *id = (int*)calloc(1,sizeof(int));
	*id = id_aeroport; // => pas de free de ce pointeur !
	//creation du point & placement
	GooCanvasItem* point=image_item(r_monde,"point_aeroport",20,20,x,y);
	//ajout d'une donnee sur l'aeroport
	g_object_set_data(G_OBJECT(point),"nature","aeroport");
	g_object_set_data(G_OBJECT(point),"id",id);
	//configuration du callback pour ca affiche les donnees sur un aeroport precis
	g_signal_connect(point,"button_press_event",(GtkSignalFunc)on_point_aeroport_presse,NULL);

	return point;
}

void placer_points();
